package com.ews.onlineexchange.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.OneToMany;
import javax.persistence.PostLoad;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import com.ews.onlineexchange.comparator.QualificationLevelComparator;
import com.ews.onlineexchange.util.SystemUUIDUtil;

/**
 * 实体名称：资质类别 说明：资质类别，包含本类资质分级信息.
 * 
 * @author admin
 *
 */
@XmlRootElement
@Entity
@NamedEntityGraph( name = "QualificationClass.ServiceDepartment", attributeNodes = {
		@NamedAttributeNode( value = "auditDepartment" )
} )
public class QualificationClass extends DataEntity {
	/**
	 * 
	 */
	private static final long	serialVersionUID	= 1L;
	
	private String					name;
	private Set<Sector>				rootSectors			= new LinkedHashSet<Sector>();
	private Set<QualificationLevel>	levelOptions		= new LinkedHashSet<>();
	private ServiceDepartment		auditDepartment;										// 资质审核部门

	@NotNull
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@XmlTransient
	@OneToMany(mappedBy = "qualificationClass", cascade = {CascadeType.PERSIST, CascadeType.MERGE},orphanRemoval = true)
	@Fetch(FetchMode.SUBSELECT)
	public Set<QualificationLevel> getLevelOptions() {
		return levelOptions;
	}
	
	@XmlTransient
	@Transient
	public List<QualificationLevel> getLevelOptionList() {
		List<QualificationLevel> resultList = new ArrayList<QualificationLevel>();
		resultList.addAll(getLevelOptions());
		return resultList;
	}
	
	@XmlTransient
	@Transient
	public List<QualificationLevel> getSortedLevelOptions() {
		List<QualificationLevel> sortedLevelOptions = new ArrayList<>();
		sortedLevelOptions.addAll(getLevelOptions());
		Collections.sort(sortedLevelOptions, new QualificationLevelComparator());
		return sortedLevelOptions;
	}

	public void setLevelOptions(Set<QualificationLevel> levelOptions) {
		this.levelOptions = levelOptions;
	}
	
	@XmlTransient
	@ManyToMany
	@Size(min = 1)
	public Set<Sector> getRootSectors() {
		return rootSectors;
	}

	public void setRootSectors(Set<Sector> rootSectors) {
		this.rootSectors = rootSectors;
	}

	
	@ManyToOne
	@NotNull
	public ServiceDepartment getAuditDepartment() {
		return auditDepartment;
	}

	public void setAuditDepartment(ServiceDepartment auditDepartment) {
		this.auditDepartment = auditDepartment;
	}
	
	@XmlTransient
	@Transient
	public String getSectorNames() {
		StringBuilder sb = new StringBuilder();
		Set<Sector> sectorList = this.getRootSectors();
		for (Sector sector : sectorList) {
			sb.append(sector.getSectorName())
				.append("，");
		}
		if (sb.length() == 0)
			return null;
		return sb.substring(0, sb.length() - 1);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((auditDepartment == null) ? 0 : auditDepartment.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
//		result = prime * result + ((rootSectors == null) ? 0 : rootSectors.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		QualificationClass other = (QualificationClass) obj;
		if (auditDepartment == null) {
			if (other.auditDepartment != null)
				return false;
		} else if (!auditDepartment.equals(other.auditDepartment))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		
		return true;
	}
	
	
	@Transient
	public String addEmptyLevelOption() {
		QualificationLevel levelOption = new QualificationLevel();
		levelOption.setQualificationClass(this);
		String uuid = SystemUUIDUtil.getUUID();
		levelOption.setLevelIndex(uuid);
		getLevelOptions().add(levelOption);
		return uuid;
	}
	
	@Transient
	public void removeLevelOption(String index) {
		Set<QualificationLevel> levels = getLevelOptions();
		QualificationLevel removeLevel = null;
		for (QualificationLevel qualificationLevel : levels) {
			if(qualificationLevel.getLevelIndex().equals(index)) {
				removeLevel = qualificationLevel;
			}
		}
		if(removeLevel != null) {
			levels.remove(removeLevel);
		}
	}
	
	@PostLoad
	private void postLoad() {
		Set<QualificationLevel> levels = getLevelOptions();
		for (QualificationLevel qualificationLevel : levels) {
			qualificationLevel.setLevelIndex(SystemUUIDUtil.getUUID());
		}
	}
}
